﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization.Json;
using System.Runtime.Serialization;
using System.Net;
using System.IO;

namespace SQLLink.DomainClasses
{
    [Serializable]
    [DataContractAttribute]
    public class GoogleDistanceMatrix
    {
        [DataMemberAttribute] public string[] destination_addresses;
        [DataMemberAttribute] public string[] origin_addresses;
        [DataMemberAttribute] public Row[] rows;
        [DataMemberAttribute] public string status;

        public List<int> GetDistanceValues()
        {
            var distanceValues = new List<int>();
            
            if (rows != null)
            {
                foreach (var row in rows)
                {
                    if (row.elements != null)
                    {
                        // Elements are objects containing distance and duration from one origin to one destination
                        foreach (var element in row.elements)
                        {
                            if (element.distance != null)
                                distanceValues.Add(element.distance.value);
                        }
                    }
                }
            }

            return distanceValues;
        }

        public List<int> GetDurationValues()
        {
            var durationValues = new List<int>();
            
            if (rows != null)
            {
                foreach (var row in rows)
                {
                    if (row.elements != null)
                    {
                        // Elements are objects containing distance and duration from one origin to one destination
                        foreach (var element in row.elements)
                        {
                            if (element.duration != null)
                                durationValues.Add(element.duration.value);
                        }
                    }
                }
            }

            return durationValues;
        }
    }

    [Serializable]
    [DataContractAttribute]
    public class Row
    {
        [DataMemberAttribute] public Element[] elements;
    }

    [Serializable]
    [DataContractAttribute]
    public class Element
    {
        [DataMemberAttribute] public Distance distance;
        [DataMemberAttribute] public Duration duration;
        [DataMemberAttribute] public string status;
    }

    [Serializable]
    [DataContractAttribute]
    public class Distance
    {
        [DataMemberAttribute] public int value;
        [DataMemberAttribute] public string text;
    }

    [Serializable]
    [DataContractAttribute]
    public class Duration
    {
        [DataMemberAttribute] public int value;
        [DataMemberAttribute] public string text;
    }

    public class GDM
    {
        public GoogleDistanceMatrix GetMatrix(string origins, string destinations)
        {
            var uri =
                new Uri(
                    string.Format(
                        "http://maps.googleapis.com/maps/api/distancematrix/json?origins={0}&destinations={1}&sensor=false&avoid=highways",
                        origins, destinations));

            var rep = GetRequest(uri);
            var gdm = new GoogleDistanceMatrix();

            using (var mem = new MemoryStream(Encoding.UTF8.GetBytes(rep)))
            {
                var ser = new DataContractJsonSerializer(gdm.GetType());
                return ser.ReadObject(mem) as GoogleDistanceMatrix;
            }
        }

        /// <summary>
        /// Méthode pour envoyer la requête http
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        private static string GetRequest(Uri uri)
        {
            var answer = string.Empty;

            var req = (HttpWebRequest) WebRequest.Create(uri);
            using (var res = (HttpWebResponse) req.GetResponse())
            {
                if (req.HaveResponse && res.StatusCode == HttpStatusCode.OK)
                    using (var resin = res.GetResponseStream())
                    {
                        if (resin != null)
                            using (var rea = new StreamReader(resin))
                            {
                                answer = rea.ReadToEnd();
                            }
                    }
            }

            return answer;
        }
    }
}
